﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Object = UnityEngine.Object;

namespace CornerMemo
{
    /// <summary>
    /// UI的筛选列表管理
    /// </summary>
    /// <typeparam name="TData">数据类型</typeparam>
    /// <typeparam name="TItem">项类型</typeparam>
    public class UIItemFilterListManager<TData, TItem>
    {
        public List<TData> DataList;
        public List<TItem> ItemList;
        public Transform ItemParent;
        public GameObject ItemPrefab;
        public int PageIndex;//当前页面索引

        private Action<TData, TItem> _showAction;
        private Action<TItem> _hideAction;
        private Func<TData, bool> _filterRules;
        private int _pageCountMax;//每页多少最多数据
        private Action _onRefreshSuccess;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="itemParent">对象的根</param>
        /// <param name="itemPrefab">预制件</param>
        /// <param name="dataList">元数据</param>
        /// <param name="showAction">显示项委托</param>
        /// <param name="hideAction">隐藏项委托</param>
        /// <param name="onRefreshSuccess">刷新成功委托</param>
        /// <param name="pageCountMax">默认每页多少数据</param>
        public UIItemFilterListManager(Transform itemParent, GameObject itemPrefab, List<TData> dataList,
            Action<TData, TItem> showAction = null, Action<TItem> hideAction = null, Action onRefreshSuccess = null
            ,int pageCountMax = 10)
        {
            DataList = dataList;
            ItemList = new List<TItem>();
            ItemParent = itemParent;
            ItemPrefab = itemPrefab;
            _showAction = showAction;
            _hideAction = hideAction;
            _pageCountMax = pageCountMax;
            _onRefreshSuccess = onRefreshSuccess;
            _filterRules = null;
            PageIndex = 0;
        }

        /// <summary>
        /// 筛选数据列表
        /// </summary>
        /// <param name="filterRules">筛选规则</param>
        private IEnumerable<TData> FilterDataList(Func<TData, bool> filterRules) =>
            filterRules == null ? DataList : DataList.Where(filterRules);
        
        /// <summary>
        /// 获取分页数据列表
        /// </summary>
        /// <param name="dataList">需要分页的数据</param>
        private List<TData> GetPageDataList(IEnumerable<TData> dataList) => dataList.Skip(PageIndex * _pageCountMax).Take(_pageCountMax).ToList();
        
        /// <summary>
        /// 刷新页面列表
        /// </summary>
        /// <param name="showAction">有数据时显示列表动作</param>
        /// <param name="hideAction">没数据时隐藏列表动作</param>
        /// <param name="dataList">列表数据</param>
        /// <param name="filterRules">列表数据筛选规则</param>
        public void RefreshPage(Action<TData, TItem> showAction = null,Action<TItem> hideAction = null
            , List<TData> dataList = null, Func<TData, bool> filterRules = null)
        {
            if (showAction != null)//如果有新的显示和隐藏动作，更新显示和隐藏动作
                _showAction = showAction;
            if (hideAction != null)
                _hideAction = hideAction;
            if (dataList != null)//如果数据列表不为空，更新数据列表
                DataList = dataList;
            
            if (filterRules != null)//筛选规则不为空时，更新筛选规则,同时页面索引重置为0
            {
                _filterRules = filterRules;
                PageIndex = 0;
            }
            //筛选规则不为空时，筛选数据列表
            dataList = GetPageDataList(FilterDataList(_filterRules));
            
            if (dataList.Count == 0)
            {
                foreach (var item in ItemList)
                {
                    _hideAction?.Invoke(item);
                }
                _onRefreshSuccess?.Invoke();
                return;
            }
            for (int i = 0; i < dataList.Count; i++)
            {
                var index = i;
                var data = dataList[i];
                if (index < ItemList.Count)
                {
                    var item = ItemList[index];
                    _showAction?.Invoke(data, item);
                }
                else
                {
                    var item = Object.Instantiate(ItemPrefab, ItemParent).GetComponent<TItem>();
                    _showAction?.Invoke(data, item);
                    ItemList.Add(item);
                }
            }
            
            if (ItemList.Count > dataList.Count)
            {
                for (int i = ItemList.Count - 1; i >= dataList.Count; i--)
                {
                    var item = ItemList[i];
                    _hideAction?.Invoke(item);
                }
            }
            _onRefreshSuccess?.Invoke();
        }

        /// <summary>
        /// 上一页
        /// </summary>
        public void PrePage()
        {
            if (PageIndex <= 0)return;
            ToPage(PageIndex - 1);
        }

        /// <summary>
        /// 下一页
        /// </summary>
        public void NextPage()
        {
            var pageMax = GetPageMax;
            if (PageIndex + 1 >= pageMax)return;
            ToPage(PageIndex + 1);
        }

        private void ToPage(int toPage)
        {
            PageIndex = toPage;
            RefreshPage();   
        }

        /// <summary>
        /// 获取最大页数
        /// </summary>
        public int GetPageMax => Mathf.CeilToInt(FilterDataList(_filterRules).Count() / (float) _pageCountMax);
        
        public void Clear()
        {
            if (ItemParent && ItemParent.childCount > 0)
            {
                ItemParent.ClearChildAll();
            }
            DataList = null;
            ItemList = null;
            ItemParent = null;
            ItemPrefab = null;
            _filterRules = null;
            PageIndex = 0;
        }
    }
}